<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <link rel="stylesheet" href="css/bootstrap.min.css" />
        <style>
            .progress-box {
                width: 400px;
                height: 470px;
                margin: 15px auto;
                position: relative;
                border-radius: 6px;
                box-shadow: 0 0 9px rgba(0,0,0,0.8);
            } 
            .progress-box::after {
                content: "";
                width: 20px;
                height: 20px;
                position: absolute;
                right: 10px;
                top: 10px;
                border-radius: 10px;
                box-shadow: inset 0 0 3px rgba(0,0,0,0.8);
            }
            .progress-box .progress {
                width: 350px;
                position: absolute;
                left: 25px;
                bottom: -5px;
                border-radius: 10px;
                box-shadow: 0 0 6px rgba(0,0,0,0.8);
            }
            .progress-box .progress-box-img {
                width: 400px;
                height: 384px;
                position: absolute;
                left: 0;
                top: 37.5px;
            }
            .progress-box .progress-box-img img {
                width: 400px;
                height: 284px;
                border-top: 2px solid grey;
                border-bottom: 2px solid grey;
            }
            .progress-box .progress-box-desc {
                width: 400px;
                height: 3em;
                line-height: 3em;
                position: absolute;
                left: 0;
                top: 321.5px;
                font-size: 1.5em;
                text-align: center;
                color: rgba(0,0,0,0.8);
                background-color: white;
                transition: background-color 0.6s ease;
            }
            .progress-box .progress-box-desc:hover {
                color: white;
                background-color: grey;
            }
            .progress-box .progress-indecator {
                width: 3em;
                height: 2em;
                line-height: 2em;
                position: absolute;
                left: calc(25px - 1.5em);
                bottom: 50px;
                border-radius: 0.5em;
                text-align: center;
                color: white;
                background-color: black;
                transition: all .6s ease;
            }
            .progress-box .progress-indecator::after {
                content: "";
                width: 0;
                height: 0;
                position: absolute;
                left: 1em;
                bottom: -1em;
                border: 0.5em solid transparent;
                border-top-color: black;
            }
        </style>
    </head>
    <body>
        <div class="progress-box" data-conponent="progress-box">
            <div class="progress-box-img">
                <img src="img/1.jpg" />
            </div>
            <div class="progress-box-desc">
                我是标题
            </div>
            <div class="progress-indecator">0%</div>
            <div class="progress">
                <div class="progress-bar progress-bar-success progress-bar-striped active"></div>
            </div>           
        </div>

        
        
        
        
        
        
        
        
        
        
        
        <script src="js/jquery-2.2.0.min.js"></script>
        <script src="js/bootstrap.js"></script>
        <script>
            class ProgressBox {
                constructor(progressBox, min = 0, max = 100) {
                    this.box = $(progressBox);
                    this.indecator = this.box.find('.progress-indecator');
                    this.bar = this.box.find('.progress-bar');
                    this.maxlength = this.box.find('.progress').width();
                    this.min = min;
                    this.max = max;
                    this.precent = 0;
                    this.onBeginCallback = this.onUpdateCallback = this.onEndCallback = () => {};
                    this.init();
                }
                init() {
                    this.precent = 0;
                    this.onBeginCallback(this);
                    this.indecate();
                    return this;
                }
                indecate() {
                    this.indecator.html(`${ this.precent }%`);
                    this.indecator.css({ left: `calc(25px - 1.5em + ${ this.precent / 100 * this.maxlength }px)`});
                    this.bar.css({ width: `${ this.precent }%` });
                }
                update(delt = 0) {
                    if(delt != 0) {
                        this.precent += delt;
                        if(this.precent > this.max) this.precent = this.max;
                        if(this.precent < this.min) this.precent = this.min;
                        this.indecate();
                    }
                    this.onUpdateCallback(this);
                    if(this.isEnd()) this.onEndCallback(this);
                }
                isBegin() {
                    return this.precent == this.min;
                }
                isEnd() {
                    return this.precent == this.max;
                }
                onEnd(callback) {
                    this.onEndCallback = callback;
                    return this;
                }
                onBegin(callback) {
                    this.onBeginCallback = callback;
                    return this;                    
                }
                onUpdate(callback) {
                    this.onUpdateCallback = callback;
                    return this;                    
                }
                bindTimer(callback, interval) {
                    let timer = setInterval(() => {
                        callback(this, timer);
                    }, interval);    
                    return this;
                }
            }
            
            $(() => {
                let progressbox = new ProgressBox('.progress-box');
                progressbox.bindTimer((that, timer) => {
                    that.isEnd() ? clearInterval(timer) : that.update(1);
                }, 100);
            });
            
            
        </script>
    </body>
</html>